// SYSTVAR.H: Pascal TVarRec support (Pascal const parameter types)
//
// 1.2
// 2002/01/02 19:50:36
//
// Copyright (c) 1997, 2002 Borland Software Corporation

#if !defined(SYSTVAR_H)
#define SYSTVAR_H

#if !defined(SystemHPP)
#error Do not include this file directly.  Include 'System.hpp'.
#endif

#if !defined(SYSMAC_H)
#include <sysmac.h>
#endif

#if !defined(DSTRING_H)
#include <dstring.h>
#endif

#if !defined(WSTRING_H)
#include <wstring.h>
#endif

#if defined(_Windows)
  #define VARIANT_NATIVE_SUPPORT
#endif

#if defined(VARIANT_NATIVE_SUPPORT)
typedef struct tagSAFEARRAY SAFEARRAY;
typedef struct tagVARIANT VARIANT;
#endif

// TVarData = VARIANT
struct TVarData
{
  union
  {
    uint16_t    VType;    // Delphi-compatible - Variant Type member
#if defined(VARIANT_NATIVE_SUPPORT)
    VARTYPE     vt;       // tagVARIANT compatible member
#endif
  };
  uint16_t Reserved1;
  uint16_t Reserved2;
  uint16_t Reserved3;
  union
  {
    // Delphi-compatible Variant members
    Smallint      VSmallint;    //  iVal
    Integer       VInteger;     //  lVal
    Single        VSingle;      //  fltVal
    Double        VDouble;      //  dblVal
    CurrencyBase  VCurrency;    //  cyVal
    TDateTimeBase VDate;        //  date
    PWideChar     VOleStr;      //  bstrVal
    IDispatch*    VDispatch;    //  pdispVal
    HResult       VError;       //  scode
    WordBool      VBoolean;     //  boolVal
    IUnknown*     VUnknown;     //  punkVal
    Byte          VByte;        //  bVal
    Shortint      VShortint;    //  charVal
    Shortint      VShortInt;    //  charVal
    Pointer       VString;      //  ??????
    PVarArray     VArray;       //  parray
    Pointer       VPointer;     //  byref
    __int64       VInt64;       //  ????
    Word          VWord;
    LongWord      VLongWord;

#if defined(VARIANT_NATIVE_SUPPORT)
    // tagVARIANT compatible members (from OAIDL.H)
    // Allowing all types marked as [V] (may appear in a VARIANT to be initialized
    LONG          lVal;
    BYTE          bVal;
    SHORT         iVal;
    FLOAT         fltVal;
    DOUBLE        dblVal;
    VARIANT_BOOL  boolVal;
    SCODE         scode;
    CY            cyVal;
    DATE          date;
    BSTR          bstrVal;
    LONG64        llVal;
    IUnknown     *punkVal;
    IDispatch    *pdispVal;
    SAFEARRAY    *parray;
    BYTE         *pbVal;
    SHORT        *piVal;
    LONG         *plVal;
    FLOAT        *pfltVal;
    DOUBLE       *pdblVal;
    VARIANT_BOOL *pboolVal;
    SCODE        *pscode;
    CY           *pcyVal;
    DATE         *pdate;
    BSTR         *pbstrVal;
    IUnknown    **ppunkVal;
    IDispatch   **ppdispVal;
    SAFEARRAY   **pparray;
    VARIANT      *pvarVal;
    PVOID         byref;
    CHAR          cVal;
    USHORT        uiVal;
    ULONG         ulVal;
    INT           intVal;
    UINT          uintVal;
    DECIMAL      *pdecVal;
    CHAR         *pcVal;
    USHORT       *puiVal;
    ULONG        *pulVal;
    INT          *pintVal;
    UINT         *puintVal;
    LONG64       *pllVal;
#endif
  };
};
typedef struct TVarData *PVarData;

#pragma option push -w-inl -w-lvc

namespace System
{
  #pragma pack(push, 1)
  typedef struct
  {
    unsigned char CallType;
    unsigned char ArgCount;
    unsigned char NamedArgCount;
    unsigned char ArgTypes[256];
  } TCallDesc, *PCallDesc;

  typedef struct
  {
    int DispID;
    unsigned char ResType;
    TCallDesc CallDesc;
  } TDispDesc, *PDispDesc;
  #pragma pack(pop)


  class   TVarRec;
  typedef TVarRec* PVarRec;

// TVarRec doesn't currently support int64:  simply adding the extra
// field breaks compatiblity with what the pascal compiler generates.
// all references to the 64-bit integers is currently ifdef'd out wit
// TVARREC64.  don't define it, it's a place holder!
#if defined(_LP64) || sizeof(long) == sizeof(__int64)
  #if !defined(TVARREC64)
    #error LP64 not yet supported
  #endif
  #define TVarRec_VLong VInt64
  #define TVarRec_vtLong vtInt64
#else
  #define TVarRec_VLong VInteger
  #define TVarRec_vtLong vtInteger
#endif

  class TVarRec
  {
  public:
    union
    {
      Integer      VInteger;
#if defined(TVARREC64)
      Largeint     VInt64;
#endif
      Boolean      VBoolean;
      Char         VChar;
      PExtended    VExtended;
      PShortString VString;
      Pointer      VPointer;
      PChar        VPChar;
      TObject*     VObject;
      TClass       VClass;
      WideChar     VWideChar;
      PWideChar    VPWideChar;
      Pointer      VAnsiString;
      PCurrency    VCurrency;
      PVariant     VVariant;
    };
    union
    {
      Byte VType;
      /*
      long ForceAlignment;
  #if 0
    //! The ForceAlignment should be removed, if alignment set to 4
    //! we don't need this
  #endif
      */
    };

    //---- constructors ----
    __fastcall TVarRec(): VType(vtInteger), VInteger(0) {} //default int 0
    __fastcall TVarRec(int src): VType(vtInteger), VInteger(src) {}
    __fastcall TVarRec(unsigned src): VType(vtInteger), VInteger(src) {}
    __fastcall TVarRec(unsigned long src): VType(TVarRec_vtLong), TVarRec_VLong(src) {}
    __fastcall TVarRec(long src): VType(TVarRec_vtLong), TVarRec_VLong(src) {}
#if defined(TVARREC64)
    __fastcall TVarRec(__int64 src): VType(vtInt64), VInt64(src) {}
    __fastcall TVarRec(unsigned __int64 src): VType(vtInt64), VInt64(src) {}
#endif
    __fastcall TVarRec(Boolean src): VType(vtBoolean), VBoolean(src) {}
    __fastcall TVarRec(char src): VType(vtChar), VChar(src) {}
    __fastcall TVarRec(const Extended& src): VType(vtExtended), VExtended(const_cast<Extended*>(&src)) {}
    __fastcall TVarRec(const ShortString& src): VType(vtString), VString(const_cast<PShortString>(&src)) {}
    __fastcall TVarRec(const Pointer src): VType(vtPointer), VPointer(src) {}
    __fastcall TVarRec(const PChar src): VType(vtPChar), VPChar(src) {}
    __fastcall TVarRec(const char* src): VType(vtPChar), VPChar(reinterpret_cast<PChar>(const_cast<char*>(src))) {}
    __fastcall TVarRec(const TObject& src): VType(vtObject), VObject(const_cast<TObject*>(&src)) {}
    __fastcall TVarRec(const TClass src): VType(vtClass), VClass(src) {}
    __fastcall TVarRec(WideChar src): VType(vtWideChar), VWideChar(src) {}
    __fastcall TVarRec(const PWideChar src): VType(vtPWideChar), VPWideChar(src) {}
    __fastcall TVarRec(const AnsiString src): VType(vtAnsiString), VAnsiString(const_cast<void*>(src.data())) {}
    __fastcall TVarRec(const Currency& src): VType(vtCurrency), VCurrency(const_cast<PCurrency>(&src)) {}
    __fastcall TVarRec(const Variant& src): VType(vtVariant), VVariant(const_cast<PVariant>(&src)) {}

    //---- assignments ----
    TVarRec& __fastcall operator =(int src)
    {
      VType = vtInteger;
      VInteger = src;
      return *this;
    }

    TVarRec& __fastcall operator =(unsigned src)
    {
      VType = vtInteger;
      VInteger = src;
      return *this;
    }

    TVarRec& __fastcall operator =(long src)
    {
      VType = TVarRec_vtLong;
      TVarRec_VLong = src;
      return *this;
    }

    TVarRec& __fastcall operator =(unsigned long src)
    {
      VType = TVarRec_vtLong;
      TVarRec_VLong = src;
      return *this;
    }

#if TVARREC64
    TVarRec& __fastcall operator =(__int64 src)
    {
      VType = vtInt64;
      VInt64 = src;
      return *this;
    }

    TVarRec& __fastcall operator =(unsigned __int64 src)
    {
      VType = vtInt64;
      VInt64 = src;
      return *this;
    }
#endif


    TVarRec& __fastcall operator =(Boolean src)
    {
      VType = vtBoolean;
      VBoolean = src;
      return *this;
    }

    TVarRec& __fastcall operator =(char src)
    {
      VType = vtChar;
      VChar = src;
      return *this;
    }

    TVarRec& __fastcall operator =(const Extended& src)
    {
      VType = vtExtended;
      VExtended = const_cast<PExtended>(&src);
      return *this;
    }

    TVarRec& __fastcall operator =(const ShortString& src)
    {
      VType = vtString;
      VString = const_cast<PShortString>(&src);
      return *this;
    }

    TVarRec& __fastcall operator =(const Pointer src)
    {
      VType = vtPointer;
      VPointer = src;
      return *this;
    }

    TVarRec& __fastcall operator =(const PChar src)
    {
      VType = vtPChar;
      VPChar = src;
      return *this;
    }

    TVarRec& __fastcall operator =(const char* src)
    {
      VType = vtPChar;
      VPChar = reinterpret_cast<PChar>(const_cast<char*>(src));
      return *this;
    }

    TVarRec& __fastcall operator =(const TObject& src)
    {
      VType = vtObject;
      VObject = const_cast<TObject*>(&src);
      return *this;
    }

    TVarRec& __fastcall operator =(const TClass src)
    {
      VType = vtClass;
      VClass = src;
      return *this;
    }

    TVarRec& __fastcall operator =(WideChar src)
    {
      VType = vtWideChar;
      VWideChar = src;
      return *this;
    }

    TVarRec& __fastcall operator =(const PWideChar src)
    {
      VType = vtPWideChar;
      VPWideChar = src;
      return *this;
    }

    TVarRec& __fastcall operator =(const AnsiString src)
    {
      VType = vtAnsiString;
      VAnsiString = const_cast<void*>(src.data());
      return *this;
    }

    TVarRec& __fastcall operator =(const Currency& src)
    {
      VType = vtCurrency;
      VCurrency = const_cast<PCurrency>(&src);
      return *this;
    }

    TVarRec& __fastcall operator =(const Variant& src)
    {
      VType = vtVariant;
      VVariant = const_cast<PVariant>(&src);
      return *this;
    }

  };

#undef TVarRec_VLong
#undef TVarRec_vtLong
}

#pragma option 			 pop

#endif
